/**
 * @file equation.h
 * @author Lishijie (lsj1018845759@outlook.com)
 * @brief 
 * @version 0.1
 * @date 2020-11-11
 * 
 * @copyright Copyright (c) 2020
 * 
 */
#ifndef _EQUATION_H_
#define _EQUATION_H_
#define TEMPLATE template<unsigned int DIM>
#include <functional>
#include <vector>

/**
 * @brief 偏微分方程基类；
 * 
 */
TEMPLATE
class Equation
{
    
public:
    typedef std::function<double(double*)> FunctionName;
    typedef std::vector<std::function<double(double*)>> FunctionNameBC;
    /**
     * @brief Set the Right Hands Term Function object
     * 
     */
    virtual void SetRightHandsTermFunction(FunctionName) = 0;
    /**
     * @brief Set the Boundary Condition Function object
     * 
     */
    virtual void SetBoundaryConditionFunction(FunctionNameBC) = 0;
    /**
     * @brief Set the Initial Condition Function object
     * 
     */
    virtual void SetInitialConditionFunction(FunctionName) = 0;
    /**
     * @brief Return Right Hands Term Function object
     * 
     * @return FunctionName 
     */
    virtual FunctionName RightHandsTermFunction() = 0;
    /**
     * @brief Return Boundary Condition Function object
     * 
     * @return FunctionNameBC 
     */
    virtual FunctionNameBC BoundaryConditionFunction() = 0;
    /**
     * @brief Return Initial Condition Function object
     * 
     * @return FunctionName 
     */
    virtual FunctionName InitialConditionFunction() = 0;
};

TEMPLATE
class PossionEquation:public Equation<DIM>
{
    typedef Equation<DIM> _base;
    typedef typename _base::FunctionName FunctionName;
    typedef typename _base::FunctionNameBC FunctionNameBC;
public:
    PossionEquation(){};
    ~PossionEquation(){};
    virtual void SetRightHandsTermFunction(FunctionName);
    virtual void SetBoundaryConditionFunction(FunctionNameBC);
    virtual void SetInitialConditionFunction(FunctionName){};
    virtual FunctionName RightHandsTermFunction(){return _F;};
    virtual FunctionNameBC BoundaryConditionFunction(){return _BCF;};
    virtual FunctionName InitialConditionFunction(){return _ICF;};
protected:
    FunctionName _F;
    FunctionNameBC _BCF;
    FunctionName _ICF;
};
TEMPLATE
void PossionEquation<DIM>::SetRightHandsTermFunction(FunctionName F)
{
    _F = F;
}

TEMPLATE 
void PossionEquation<DIM>::SetBoundaryConditionFunction(FunctionNameBC BCF)
{
    _BCF = BCF;
}

#undef TEMPLATE
#else
#endif


